<template>
	<view class="content qa-content">
		<TopVue />
		<view class="qa-main">
			<YuyingVue :sayIng="sayFlag" :tipsWords="'按住下方语音按钮描述你的病症'" />
			<view class="msg-box">
				<view class="msg-list" v-for="(item,idx) in msgList">
					<view class="my-msg" v-if="item.problem">
						<view class="my-msg-panel">{{item.problem}}</view>
						<view class="iconfont c-danger">&#xe74b; 删除</view>
					</view>
					<view class="msg-type">
						<view class="msg-type-panel" v-if="item.sendLoading">
							大健康AI助手思考中
							<span class="sendIng">.</span>
							<span class="sendIng">.</span>
							<span class="sendIng">.</span>
						</view>
						<view class="msg-type-panel" v-else-if="item.isTimeout">
							服务器繁忙
						</view>
						<view class="msg-type-panel" v-else>
							<!-- 思考完成 -->
						</view>
					</view>
					<!-- <div class="msg-process"></div> -->
					<view class="msg-answer">
						<view class="answer-panel" v-show="item.answer">
							<view ref="domStr">{{item.answer}}</view>
							<view>
								<text class="suggestion" v-for="suggestion in item.suggestion">{{suggestion}}</text>
							</view>
							<view v-if="item.goodsList && item.goodsList.length>0">
								<view class="goods-paneltitle">产品推荐</view>
								<view class="goods-parent">
									<view class="goods-list" v-for="goods in item.goodsList"
										@click="jump('/pages/index/goodsDetail')">
										<image class="goods-img" src="/static/qrcode.png" mode="aspectFit"></image>
										<view style="width: 100rpx;flex-grow: 1;">
											<view class="goods-title no-warp">{{goods.title}}</view>
											<view class="goods-info">产品成分：</view>
											<view class="goods-info">{{goods.info}}</view>
										</view>
									</view>
								</view>
							</view>
						</view>
					</view>
				</view>
			</view>
			<view class="bottom-box">
				<view class="bottom-btn" :class="loading ? 'button-disabled':'bottom-btn'" @click="clickBtn">
					<text class="iconfont">&#xe905;</text>
					{{voiceOptionText}}
				</view>
			</view>
		</view>
		<view id="audioPlayer"></view>
	</view>
</template>

<script setup lang="ts">
	import { onMounted, reactive, ref } from 'vue';
	import TopVue from '@/components/top.vue'
	import YuyingVue from '@/components/Yuying.vue'
	import commonApi from '../../common/api/commonApi';
	const answerList = ref([])
	const msgList = ref([])
	const answerTimmer = ref({})
	const voiceOptionText = ref('点击语音输入')
	const voiceOptionContent = ref('')
	const sayFlag = ref(false)
	const loading = ref(false)
	onMounted(() => {
		const audioElement = document.createElement('audio');
		audioElement.src = '/static/audio.m4a'
		audioElement.id = 'audio';
		const audioParent = document.getElementById('audioPlayer')
		audioElement.addEventListener('ended', () => {
			console.log('end')
			loading.value = false
			voiceOptionText.value = '点击语音输入'
		})
		audioParent.appendChild(audioElement);
	})
	const ontouchend = async () => {
		const audioElement:any = document.getElementById('audio');
		audioElement.muted = true;
		audioElement.play();
		audioElement.pause()
		console.log('抬起了按钮');
		if (voiceOptionText.value === "点击发送") {
			loading.value = true
			uni.showLoading({
				mask: true,
			})
			sayFlag.value = false
			voiceOptionText.value = "大健康AI助手正在回复您..."
			setTimeout(async () => {
				await sendContent()
				audioElement.muted = false;
				audioElement.play();
				console.info(456)
				//recognition.value.stop();
			}, 1500)


		}
	}
	const showAnswer = (key) => {
		if (answerTimmer.value[key]) return;
		let data = ''

		answerTimmer.value[key] = setTimeout(() => {
			answerList.value[key].reduce((prev, item, index) => {
				if (item === '') {
					item = ' '
				}
				if (item !== '#' && answerList.value[key][index + 1] === '#' && answerList.value[key][index + 2] === '#' && answerList.value[key][index + 3] === '#') {
					item = item + '<br/>'
				}
				if (item === '#' && answerList.value[key][index - 2] === '#' && answerList.value[key][index - 1] === '#') {
					item = item + '<br/>'
				}
				if (item === '-' && prev === ' ') {
					item = "<br/>-"
				}
				data += item
			}, '')
			msgList.value[key].markerHtml = ''
			msgList.value[key].answer = data;
		}, 500);
	}
	const base64ToArrayBuffer = (base64) => {
		try {
			// 1. 移除数据URL前缀（增强正则兼容性）
			const base64Data = base64.replace(/^data:[^;]+;base64,/, '');

			// 2. 处理URL安全Base64字符并补全填充
			const sanitizedBase64 = base64Data
				.replace(/-/g, '+')  // 替换URL安全字符 '-'
				.replace(/_/g, '/')  // 替换URL安全字符 '_'
				.padEnd(base64Data.length + (4 - (base64Data.length % 4)) % 4, '='); // 补全等号

			// 3. 解码Base64为二进制字符串
			const binaryString = atob(sanitizedBase64);

			// 4. 高效创建ArrayBuffer
			const buffer = new ArrayBuffer(binaryString.length);
			const bytes = new Uint8Array(buffer);
			for (let i = 0; i < binaryString.length; i++) {
				bytes[i] = binaryString.charCodeAt(i);
			}
			return buffer;
		} catch (error) {
			console.error('Base64转换失败:', error);
			throw new Error('无效的Base64数据: ' + error.message);
		}
	}
	//语音输入后请求后端接口
	const voiceChat = () => {
		console.log('开始语音输入');
		sayFlag.value = true
		// 录制音频逻辑 浏览器
		if ('webkitSpeechRecognition' in window) {
			const recognition = new ((window as any).SpeechRecognition || (window as any).webkitSpeechRecognition)(); // 注意这里用的是webkit前缀，因为标准的SpeechRecognition在某些浏览器中可能需要前缀或者polyfill。
			recognition.lang = 'zh-CN'; // 设置语言为中文
			recognition.interimResults = false; // 设置为false，表示只返回最终结果，不返回中间结果

			recognition.onresult = (event) => {
				const last = event.results.length - 1;
				const speechRes = event.results[last][0].transcript; // 获取识别结果并赋值给data中的transcript
				voiceOptionContent.value = speechRes

			};
			recognition.onerror = (event) => {
				console.log(event)
				console.error('Speech recognition error:', event.error);
			};
			recognition.start(); // 开始语音识别
			voiceOptionText.value = '点击发送'
		} else {
			alert('您的浏览器不支持语音识别功能');
		}

	}
	//将语音输入的参数传给后端
	const sendContent = async () => {
		let qus = voiceOptionContent.value

		if (!qus) {
			uni.showToast({
				title: '您好像没有说话，请长按按钮询问问题',
				icon: 'none',
			})
			loading.value = false
			voiceOptionText.value = '点击语音输入'
			return
		}
		showQus(qus)
		const key = msgList.value.length - 1;
		const res = await commonApi.getInfo(qus)
		if (res && res.text) {
			//将回复的文字展示
			let resText = res.text
			const list = msgList.value
			list[key].sendLoading = false
			msgList.value = list
			const answerArr = []
			answerArr[key] = [resText]
			answerList.value = answerArr
			showAnswer(key)
			let audioBuffer = base64ToArrayBuffer(res.audio)
			const blob = new Blob([audioBuffer], { type: 'audio/wav' })
			let url = URL.createObjectURL(blob)

			voiceOptionContent.value = '';
			uni.hideLoading();

			const audioElement : any = document.getElementById('audio');
			audioElement.src = url;

		}
	}
	//语音输入语音回复的问答展示
	const showQus = (qus) => {
		const list = msgList.value
		list.push({
			problem: qus + "",
			answer: "",
			sendLoading: true,
			isTimeout: false,
		});
		msgList.value = list
	}
	const btnType = ref('wait')
	const clickBtn = () => {
		if (btnType.value === 'wait') {
			btnType.value = 'sending'
			voiceChat()
		} else {
			btnType.value = 'wait'
			ontouchend()
		}
	}
	const jump = (url) => {
		uni.navigateTo({
			url
		})
	}
</script>
<style lang="scss">
	.sendIng {
		display: inline-block;
		font-size: 56rpx;
		line-height: 0;
	}

	.sendIng:nth-child(1) {
		animation: sendIngAnimation 2s linear 0.5s infinite;
	}

	.sendIng:nth-child(2) {
		animation: sendIngAnimation 2s linear 1s infinite;
	}

	.sendIng:nth-child(3) {
		animation: sendIngAnimation 2s linear 1.5s infinite;
	}

	@keyframes sendIngAnimation {
		0% {
			transform: translateY(0);
			opacity: 1;
		}

		25% {
			transform: translateY(-10rpx);
			opacity: 1;
		}

		50% {
			transform: translateY(0);
			opacity: 1;
		}

		75% {
			transform: translateY(10rpx);
			opacity: 1;
		}

		100% {
			transform: translateY(0);
			opacity: 1;
		}
	}

	.qa-content {
		.qa-main {
			padding: 0 20rpx;
			background-color: #F6F6F6;
			min-height: calc(100vh - 100rpx);
			display: flex;
			flex-direction: column;
		}

		.msg-box {
			padding-bottom: 100rpx;
			height: 50vh;
			flex-grow: 1;
			overflow: auto;

			.my-msg {
				text-align: right;
			}

			.msg-answer,
			.my-msg {
				font-size: 28rpx;
				font-weight: bold;
				color: #1E1E1E;
				padding: 10rpx 0rpx;
			}

			.answer-panel,
			.my-msg-panel {
				text-align: left;
				padding: 10rpx 20rpx;

				max-width: 80%;
				display: inline-block;
			}

			.my-msg-panel {
				background: rgba(0, 122, 255, 0.2);
				border-radius: 20rpx 0 20rpx 20rpx;
			}

			.answer-panel {
				background: #FFFFFF;
				border: 1rpx solid rgba(16, 53, 151, 0.1);
				border-radius: 0rpx 20rpx 20rpx 20rpx;
			}

			.iconfont {
				font-weight: lighter;
				font-size: 26rpx;
				margin-top: 10rpx;
			}

			.suggestion {
				font-weight: 400;
				font-size: 13rpx;
				color: #2F65F3;
				margin-right: 5rpx;
			}

			.goods-parent {
				min-width: 600rpx;
			}

			.goods-paneltitle {
				font-weight: 500;
				font-size: 16rpx;
				color: #1E1E1E;
				margin-top: 20rpx;
				margin-bottom: 10rpx;
			}

			.goods-list {
				display: inline-flex;
				align-items: center;
				background-color: #EDEDED;
				padding: 5rpx;
				border-radius: 4rpx;
				width: 250rpx;
				margin-right: 10rpx;
				margin-borrom: 10rpx;
			}

			.goods-img {
				width: 100rpx;
				height: 100rpx;
				margin-right: 5rpx;
				flex-shrink: 0;
			}

			.goods-title {
				font-weight: 500;
				font-size: 14rpx;
				color: #1E1E1E;
				margin-bottom: 10rpx;
			}

			.goods-info {
				font-size: 12rpx;
				color: #4E4E4E;
				font-weight: lighter;
			}
		}

		.bottom-box {
			position: fixed;
			bottom: 0rpx;
			width: 100%;
			left: 0;
			padding: 0 20rpx 20rpx 20rpx;
			background-color: #F6F6F6;

			.bottom-btn {
				color: #fff;
				background-color: #2F65F3;
				display: flex;
				align-items: center;
				justify-content: center;
				height: 80rpx;
				border-radius: 10rpx;
				-webkit-user-select: none;
				-moz-user-select: none;
				-ms-user-select: none;
				user-select: none;
				-webkit-touch-callout: none;

				.iconfont {
					margin-right: 10rpx;
					font-size: 32rpx;
				}
			}

			.button-disabled {
				background-color: #dedede;
				pointer-events: none;
			}
		}
	}
</style>